package org.zoomdev.zoom.dao.ddl.utils;

import org.zoomdev.zoom.dao.annotations.*;
import org.zoomdev.zoom.dao.ddl.SqlType;
import org.zoomdev.zoom.dao.meta.ColumnMeta;
import org.zoomdev.zoom.dao.meta.IndexMeta;
import org.zoomdev.zoom.dao.meta.TableMeta;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class BeanToTableMetaParser {

    // 默认字符串长度
    private static final int DEFAULT_STRING_LENGTH = 255;

    /**
     * 解析 Java Bean 类为 TableMeta
     *
     * @param clazz     Java Bean 类
     * @param tableName 表名（如果为null，则使用类名转换）
     * @return TableMeta 对象
     */
    public static TableMeta parse(Class<?> clazz, String tableName) {
        TableMeta tableMeta = new TableMeta();

        // 设置表名
        if (tableName == null || tableName.isEmpty()) {
            tableName = convertClassNameToTableName(clazz.getSimpleName());
        }
        tableMeta.setName(tableName);

        // 处理表注解
        Table tableAnnotation = clazz.getAnnotation(Table.class);
        if (tableAnnotation != null) {
            tableMeta.setComment(tableAnnotation.comment());
            tableMeta.setEngine(tableAnnotation.engine());
        } else {
            tableMeta.setEngine("InnoDB"); // 默认引擎
        }

        // 解析字段
        List<ColumnMeta> columns = new ArrayList<>();
        List<String> primaryKeys = new ArrayList<>();
        List<IndexMeta> indexes = new ArrayList<>();

        for (Field field : clazz.getDeclaredFields()) {
            ColumnMeta columnMeta = parseField(field);
            columns.add(columnMeta);

            // 处理主键
            if (field.isAnnotationPresent(PrimaryKey.class)) {
                primaryKeys.add(columnMeta.getName());

                // 处理自增
                if (field.isAnnotationPresent(AutoGenerate.class)) {
                    columnMeta.setAutoIncrement(true);
                }
            }

            // 处理索引
            if (field.isAnnotationPresent(Index.class)) {
                Index indexAnnotation = field.getAnnotation(Index.class);
                IndexMeta indexMeta = new IndexMeta();
                indexMeta.setName(indexAnnotation.name().isEmpty() ?
                        "idx_" + columnMeta.getName() : indexAnnotation.name());
                indexMeta.setColumns(new String[]{columnMeta.getName()});
                indexMeta.setUnique(indexAnnotation.unique());
                indexes.add(indexMeta);
            }
        }

        // 设置列
        tableMeta.setColumns(columns.toArray(new ColumnMeta[0]));

        // 设置主键
        if (!primaryKeys.isEmpty()) {
            tableMeta.setPrimaryKeys(primaryKeys.toArray(new String[0]));
        }

        // 设置索引
        if (!indexes.isEmpty()) {
            tableMeta.setIndexes(indexes.toArray(new IndexMeta[0]));
        }

        return tableMeta;
    }

    /**
     * 解析字段为 ColumnMeta
     */
    private static ColumnMeta parseField(Field field) {
        ColumnMeta columnMeta = new ColumnMeta();

        // 设置列名
        Column columnAnnotation = field.getAnnotation(Column.class);
        if (columnAnnotation != null && !columnAnnotation.value().isEmpty()) {
            columnMeta.setName(columnAnnotation.value());
        } else {
            columnMeta.setName(convertFieldNameToColumnName(field.getName()));
        }

        // 设置类型
        Class<?> fieldType = field.getType();
        SqlType sqlType = SqlType.fromJavaType(fieldType);
        columnMeta.setType(sqlType);

        // 设置长度/精度
        if (columnAnnotation != null && columnAnnotation.size() > 0) {
            columnMeta.setSize(columnAnnotation.size());
        } else if (sqlType.isString() && sqlType.hasLength()) {
            columnMeta.setSize(DEFAULT_STRING_LENGTH);
        } else if (sqlType.hasScale()) {
            columnMeta.setSize(10); // 默认精度
            columnMeta.setScale(2); // 默认小数位数
        }

        // 设置是否允许为空
        columnMeta.setNotNull(columnAnnotation == null || !columnAnnotation.notNull());

        // 设置默认值
        if (columnAnnotation != null && !columnAnnotation.defaultValue().isEmpty()) {
            columnMeta.setDefaultValue(columnAnnotation.defaultValue());
        }

        // 设置注释
        if (columnAnnotation != null && !columnAnnotation.comment().isEmpty()) {
            columnMeta.setComment(columnAnnotation.comment());
        }

        // 处理枚举/SET类型
        if (sqlType == SqlType.ENUM || sqlType == SqlType.SET) {
            if (fieldType.isEnum()) {
                Object[] enumConstants = fieldType.getEnumConstants();
                String[] values = new String[enumConstants.length];
                for (int i = 0; i < enumConstants.length; i++) {
                    values[i] = enumConstants[i].toString();
                }
                columnMeta.setValues(values);
            }
        }

        return columnMeta;
    }

    /**
     * 将类名转换为表名（驼峰转下划线）
     */
    private static String convertClassNameToTableName(String className) {
        return camelToUnderline(className);
    }

    /**
     * 将字段名转换为列名（驼峰转下划线）
     */
    private static String convertFieldNameToColumnName(String fieldName) {
        return camelToUnderline(fieldName);
    }

    /**
     * 驼峰命名转下划线命名
     */
    private static String camelToUnderline(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }

        StringBuilder result = new StringBuilder();
        result.append(Character.toLowerCase(str.charAt(0)));

        for (int i = 1; i < str.length(); i++) {
            char c = str.charAt(i);
            if (Character.isUpperCase(c)) {
                result.append('_').append(Character.toLowerCase(c));
            } else {
                result.append(c);
            }
        }

        return result.toString();
    }


}